package com.prd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.prd.dto.*;
import com.prd.enums.CustomerRemarkEnum;
import com.prd.mapper.CustomerVisitMapper;
import com.prd.model.CustomerVisitDO;
import com.prd.service.*;
import com.prd.tools.CopyNonNullBeanUtils;
import com.prd.util.JsonData;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户-项目 服务实现类
 * </p>
 *
 * @author o1
 * @since 2023-12-26
 */
@Service(value = "CustomerVisitService")
public class CustomerVisitServiceImpl extends ServiceImpl<CustomerVisitMapper, CustomerVisitDO> implements CustomerVisitService {

    @Autowired
    private CustomerVisitMapper visitMapper;


    @Resource(name = "CustomerService")
    private CustomerService customerService;
    @Resource(name = "CustomerGuestService")
    private CustomerGuestService guestService;
    @Resource(name = "CustomerProjectService")
    private CustomerProjectService projectService;
    @Resource(name = "CustomerRemarkService")
    private CustomerRemarkService remarkService;


    @Override
    public Map<String, Object> uSearch(int page, int size, Date date, int businessManagerId, int status) {
        LambdaQueryWrapper<CustomerVisitDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CustomerVisitDO::getBusinessManagerId, businessManagerId);
        lambdaQueryWrapper.eq(CustomerVisitDO::getStatus, status);
        lambdaQueryWrapper.eq(CustomerVisitDO::getVisitDate, date);
        Page<CustomerVisitDO> pageInfo = new Page<>(page, size);
        IPage<CustomerVisitDO> visitDOIPage = visitMapper.selectPage(pageInfo,lambdaQueryWrapper);
        List<CustomerVisitDTO> visitDTOList = visitDOIPage.getRecords().stream().map(
                this::doToDto
        ).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>(3);
        map.put("total_record", visitDOIPage.getTotal());
        map.put("total_page", visitDOIPage.getPages());
        map.put("current_data", visitDTOList);
        return map;
    }

    @Override
    public JsonData uAdd(CustomerVisitDTO visitDTO) {
        String visitNo = String.valueOf(visitDTO.hashCode());
        LambdaQueryWrapper<CustomerVisitDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CustomerVisitDO::getVisitNo, visitNo);
        lambdaQueryWrapper.eq(CustomerVisitDO::getBusinessManagerId, visitDTO.getBusinessManagerId());
        CustomerVisitDO visitDO = visitMapper.selectOne(lambdaQueryWrapper);
        if (visitDO == null) {
            visitDO = new CustomerVisitDO();
            visitDO.setVisitNo(visitNo);
            CopyNonNullBeanUtils.copyProperties(visitDTO, visitDO);
            visitMapper.insert(visitDO);
            if (visitDTO.getOtherBusinessManagerList() != null && visitDTO.getOtherBusinessManagerList().size() > 1) {
                for (CustomerTmpEmployeeDTO employeeDTO: visitDTO.getOtherBusinessManagerList()) {
                    if (employeeDTO.getBusinessManagerId() != visitDTO.getBusinessManagerId()) {
                        visitDTO.setBusinessManager(employeeDTO.getBusinessManager());
                        visitDTO.setBusinessManagerId(employeeDTO.getBusinessManagerId());
                        visitDTO.setBusinessPhone(employeeDTO.getBusinessPhone());
                        visitDTO.setBusinessDepartment(employeeDTO.getBusinessDepartment());
                        visitDTO.setBusinessDepartmentId(employeeDTO.getBusinessDepartmentId());
                        addOtherVisit(visitNo, visitDTO);
                    }
                }
            }
            if (visitDTO.getGoalRemark() != null) {
                CustomerRemarkDTO goalRemarkDto = visitDTO.getGoalRemark();
                goalRemarkDto.setType(CustomerRemarkEnum.VisitGoal.getCode());
                goalRemarkDto.setNo(visitNo);
                remarkService.uAdd(goalRemarkDto);
            }
            return JsonData.buildSuccess(visitDO);
        }
        else
            return new JsonData(-1, visitDO, "已有拜访任务");
    }

    @Override
    public JsonData uDetail(String visitNo, int businessManagerId, int status) {
        LambdaQueryWrapper<CustomerVisitDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CustomerVisitDO::getVisitNo, visitNo);
        lambdaQueryWrapper.eq(CustomerVisitDO::getBusinessManagerId, businessManagerId);
        if (status > 0)
            lambdaQueryWrapper.eq(CustomerVisitDO::getStatus, status);
        CustomerVisitDO visitDO = visitMapper.selectOne(lambdaQueryWrapper);
        if (visitDO != null) {
            CustomerVisitDTO visitDTO = new CustomerVisitDTO();
            CopyNonNullBeanUtils.copyProperties(visitDO, visitDTO);
            if (visitDO.getCustomerNo() != null) {
                visitDTO.setCustomerDTO(customerService.getOne(visitDO.getCustomerNo()));
                if (visitDO.getProjectId() != null && visitDO.getProjectId().indexOf(",") != 0) {
                    List<String> projectIdList = Arrays.asList(visitDO.getGuestNo().split(","));
                    List<CustomerProjectDTO> projectDTOList = projectService.searchForList(visitDO.getCustomerNo());
                    List<CustomerProjectDTO> targetProjectList = new ArrayList<>();
                    projectDTOList.forEach(projectDTO -> {
                        if (projectIdList.contains(projectDTO.getProjectId()))
                            targetProjectList.add(projectDTO);
                    });
                    visitDTO.setProjectDTOList(targetProjectList);
                }
            }
            if (visitDO.getGuestNo() != null && visitDO.getGuestNo().indexOf(",") != 0) {
                List<String> guestNoList = Arrays.asList(visitDO.getGuestNo().split(","));
                List<CustomerGuestDTO> targetProjectList = new ArrayList<>();
                for (String guestNo: guestNoList) {
                    targetProjectList.add(guestService.getOneByGuestNo(guestNo));
                }
                visitDTO.setGuestDTOList(targetProjectList);
            }

            LambdaQueryWrapper<CustomerVisitDO> otherWrapper = new LambdaQueryWrapper<>();
            otherWrapper.eq(CustomerVisitDO::getVisitNo, visitNo);
            if (visitMapper.selectCount(otherWrapper) > 1) {
                List<CustomerVisitDO> otherVisitDOList = visitMapper.selectList(otherWrapper);
                for (CustomerVisitDO otherVisitDO: otherVisitDOList) {
                    if (otherVisitDO.getBusinessManagerId() != businessManagerId) {
                        CustomerTmpEmployeeDTO tmpEmployeeDTO = new CustomerTmpEmployeeDTO();
                        CopyNonNullBeanUtils.copyProperties(otherVisitDO, tmpEmployeeDTO);
                        visitDTO.getOtherBusinessManagerList().add(tmpEmployeeDTO);
                    }
                }
            }
            return JsonData.buildSuccess(visitDTO);
        }
        else
            return JsonData.buildError("未找到对应拜访记录");
    }

    @Override
    public JsonData uAddBusinessManager(String visitNo, int businessManagerId, String businessManager, int businessDepartmentId, String businessDepartment, String businessPhone) {
        LambdaQueryWrapper<CustomerVisitDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CustomerVisitDO::getVisitNo, visitNo);
        lambdaQueryWrapper.eq(CustomerVisitDO::getBusinessManagerId, businessManagerId);
        CustomerVisitDO visitDO = visitMapper.selectOne(lambdaQueryWrapper);
        if (visitDO == null) {
            visitDO = new CustomerVisitDO();
            visitDO.setVisitNo(visitNo);
            LambdaQueryWrapper<CustomerVisitDO> otherWrapper = new LambdaQueryWrapper<>();
            otherWrapper.eq(CustomerVisitDO::getVisitNo, visitNo);
            if (visitMapper.selectCount(otherWrapper) > 1) {
                List<CustomerVisitDO> otherVisitDOList = visitMapper.selectList(otherWrapper);
                CustomerVisitDO otherVisitDO = otherVisitDOList.get(0);
                CopyNonNullBeanUtils.copyProperties(otherVisitDO, visitDO);
                visitDO.setBusinessManager(businessManager);
                visitDO.setBusinessManagerId(businessManagerId);
                visitDO.setBusinessDepartment(businessDepartment);
                visitDO.setBusinessDepartmentId(businessDepartmentId);
                visitDO.setBusinessPhone(businessPhone);
                visitMapper.insert(visitDO);
            }
            return JsonData.buildSuccess(visitDO);
        }
        else
            return JsonData.buildError("没有找到对应的拜访任务");
    }

    @Override
    public JsonData uUpdate(CustomerVisitDTO visitDTO) {
        LambdaQueryWrapper<CustomerVisitDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CustomerVisitDO::getVisitNo, visitDTO.getVisitNo());
        lambdaQueryWrapper.eq(CustomerVisitDO::getBusinessManagerId, visitDTO.getBusinessManagerId());
        CustomerVisitDO visitDO = visitMapper.selectOne(lambdaQueryWrapper);
        if (visitDO == null) {
            return JsonData.buildError("未找到对应拜访任务");
        }else {
            CopyNonNullBeanUtils.copyProperties(visitDTO, visitDO);
            if (visitDTO.getOtherBusinessManagerList() != null && visitDTO.getOtherBusinessManagerList().size() > 1) {
                for (CustomerTmpEmployeeDTO employeeDTO: visitDTO.getOtherBusinessManagerList()) {
                    if (employeeDTO.getBusinessManagerId() != visitDTO.getBusinessManagerId()) {
                        CustomerVisitDTO otherVisitDTO = new CustomerVisitDTO();
                        CopyNonNullBeanUtils.copyProperties(visitDTO, otherVisitDTO);
                        otherVisitDTO.getGuestDTOList().clear();
                        otherVisitDTO.setBusinessManager(employeeDTO.getBusinessManager());
                        otherVisitDTO.setBusinessManagerId(employeeDTO.getBusinessManagerId());
                        otherVisitDTO.setBusinessPhone(employeeDTO.getBusinessPhone());
                        otherVisitDTO.setBusinessDepartment(employeeDTO.getBusinessDepartment());
                        otherVisitDTO.setBusinessDepartmentId(employeeDTO.getBusinessDepartmentId());
                        uUpdate(otherVisitDTO);
                    }
                }
            }
            visitMapper.update(visitDO, lambdaQueryWrapper);
            if (visitDTO.getResultRemark() != null) {
                CustomerRemarkDTO resultRemarkDto = visitDTO.getResultRemark();
                resultRemarkDto.setType(CustomerRemarkEnum.VisitResultReport.getCode());
                resultRemarkDto.setNo(visitDO.getVisitNo());
                remarkService.uAdd(resultRemarkDto);
            }
            if (visitDTO.getReplenishRemarkList() != null && visitDTO.getReplenishRemarkList().size() > 0) {
                for (CustomerRemarkDTO replenishRemarkDto: visitDTO.getReplenishRemarkList()) {
                    replenishRemarkDto.setType(CustomerRemarkEnum.VisitReplenish.getCode());
                    replenishRemarkDto.setNo(visitDTO.getVisitNo());
                    remarkService.uUpdateAndAdd(replenishRemarkDto);
                }
            }
            return JsonData.buildSuccess(visitDO);
        }
    }

    @Override
    public JsonData uFinish(CustomerVisitDTO visitDTO) {
        visitDTO.setStatus(4);
        visitDTO.setVisitFinishDate(new Date());
        return uUpdate(visitDTO);
    }

    @Override
    public JsonData uArrival(CustomerVisitDTO visitDTO) {
        visitDTO.setStatus(2);
        visitDTO.setVisitActualDate(new Date());
        return uUpdate(visitDTO);
    }

    private void addOtherVisit(String visitNo, CustomerVisitDTO visitDTO) {
        LambdaQueryWrapper<CustomerVisitDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CustomerVisitDO::getVisitNo, visitNo);
        lambdaQueryWrapper.eq(CustomerVisitDO::getBusinessManagerId, visitDTO.getBusinessManagerId());
        CustomerVisitDO visitDO = visitMapper.selectOne(lambdaQueryWrapper);
        if (visitDO == null) {
            visitDO = new CustomerVisitDO();
            visitDO.setVisitNo(visitNo);
            CopyNonNullBeanUtils.copyProperties(visitDTO, visitDO);
            visitMapper.insert(visitDO);
        }
    }


    private CustomerVisitDTO doToDto(CustomerVisitDO visitDO) {
        CustomerVisitDTO visitDTO = new CustomerVisitDTO();
        BeanUtils.copyProperties(visitDO, visitDTO);
        return visitDTO;
    }
}
